/*
 * #%L
 * SwiftUIWeb Maven Webapp
 * $Id:$
 * $HeadURL:$
 * %%
 * Copyright (C) 2011 - 2012 Linkwithweb
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 3 of the 
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public 
 * License along with this program.  If not, see
 * <http://www.gnu.org/licenses/gpl-3.0.html>.
 * #L%
 */
package com.linkwithweb.products.swiftui.filters;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

import com.linkwithweb.products.swiftui.context.RequestContext;
import com.linkwithweb.products.swiftui.context.SystemContext;
import com.linkwithweb.products.swiftui.context.UserContext;
import com.linkwithweb.products.swiftui.dataobject.FrameworkUser;
import com.linkwithweb.products.swiftui.service.PlatformService;
import com.linkwithweb.products.swiftui.ui.wrapper.CustomRequestWrapper;
import com.linkwithweb.products.swiftui.utils.ServiceLocator;

/**
 * Servlet Filter implementation class CydcorSecurityFilter
 */
public class GenericSecurityFilter implements Filter {
	protected final Log logger = LogFactory.getLog(getClass());
	@Autowired
	@Qualifier("platformService")
	private PlatformService platformService;

	/**
	 * @return
	 */
	public PlatformService getPlatformService() {
		if (platformService == null) {
			platformService = (PlatformService) ServiceLocator.getService("platformService");
		}
		return platformService;
	}

	/**
	 * Default constructor.
	 */
	public GenericSecurityFilter() {
		// TODO Auto-generated constructor stub
	}

	/**
	 * @see Filter#destroy()
	 */
	public void destroy() {
		// TODO Auto-generated method stub
	}

	/**
	 * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
	 */
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
			ServletException {
		propogate(request, response, chain);
	}

	/**
	 * Add Db Connection and user Info in RequestContext and propogate
	 * 
	 * @param request
	 * @param response
	 * @param chain
	 * @throws IOException
	 * @throws ServletException
	 */
	private void propogate(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
			ServletException {
		RequestContext requestContext = null;
		try {
			// Wrap Request so as we can extend it's existing Functionality
			CustomRequestWrapper requestWrapper = new CustomRequestWrapper((HttpServletRequest) request);

			requestContext = new RequestContext();
			requestContext.setRequestWrapper(requestWrapper);
			SystemContext.getInstance().setRequestContext(requestContext);

			String requestURI = requestContext.getRequestWrapper().getRequestURL().toString();

			String mediUser = requestContext.getRequestWrapper().getParameter("mediUser");
			String mediPassword = requestContext.getRequestWrapper().getParameter("mediPass");
			String clientIdentifier = requestContext.getRequestWrapper().getParameter("identifier");

			
			UserContext userContext = new UserContext();
			userContext.setUserId(mediUser);
			userContext.setUserName(mediUser);
			userContext.setPassword(mediPassword);
			SystemContext.getInstance().getClientName().set(clientIdentifier);
			
			if(SystemContext.getInstance().getMessages() == null){
				SystemContext.getInstance().resetErrorList();
			}

			if (StringUtils.containsIgnoreCase(requestURI, "securityHandler")|| StringUtils.containsIgnoreCase(requestURI, "/assets/")|| StringUtils.containsIgnoreCase(requestURI, "/loginadapter")) {
				chain.doFilter(request, response);
			} else {
				boolean passwordMatches = true;

				FrameworkUser user = getPlatformService().loadUser(mediUser, mediPassword);
				if(user == null){
					return;
				}
				
				if(user.getListOfRoles() != null && !user.getListOfRoles().isEmpty()){
					userContext.setRole(user.getListOfRoles().get(0).getRoleId());
				}

				userContext.setFrameworkUser(user);

				//userContext.setSchemaName(user.getListOfApplications().get(0));
				userContext.setIdentifier(user.getListOfApplications().get(0).getAppId());

				SystemContext.getInstance().setUserContext(userContext);
				getPlatformService().loadAndStoreDataSource(null, null, null, null);
				// if (StringUtils.equals(SystemContext.getInstance()
				// .getLoggedInUsers().get(mediUser), mediPassword)) {
				// passwordMatches = true;
				// }
				/**
				 * if Authenitcated move on else leave out
				 */
				if (passwordMatches) {
					chain.doFilter(request, response);
				}
			}
		} catch (Throwable th) {
			logger.fatal("Exception in Security Filter:", th);
			th.printStackTrace();
		} finally {
			response.flushBuffer();
			SystemContext.getInstance().setRequestContext(null);
		}

	}

	/**
	 * @see Filter#init(FilterConfig)
	 */
	public void init(FilterConfig fConfig) throws ServletException {
		// TODO Auto-generated method stub
	}

}
